package com.kc.sjwh.other;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AccountException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
 * 异常处理逻辑
 * date: 2017年5月17日
 * @author zhangGuihua(hua7381@163.com)
 */
public class ExceptionHandler implements HandlerExceptionResolver {
	static Logger logger = Logger.getLogger(ExceptionHandler.class);

	/**
	 * 处理异常
	 */
	public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) {
		String errMsg = null;
		
		if(ex instanceof IllegalArgumentException 
				|| ex instanceof AccountException) {//用异常实现的业务逻辑,并非错误
			errMsg = ex.getMessage();
		} else {//是错误的异常
			if(ex instanceof RuntimeException && ex.getCause()!=null) {//对"必须catche的异常"的包装
				ex = (Exception)ex.getCause();
			}
			
			if(ex.getMessage().contains("ORA-12899")) {
				errMsg = "输入的某项超出其长度范围";
			} else {
				errMsg = "非常抱歉，系统发生了内部错误。";
				logger.error(getTrace(ex));
			}
			
		}

		if (isAjax(req)) {
			resp.setStatus(500);
			resp.setContentType("application/json;charset=UTF-8");
			write(resp, errMsg);
			return new ModelAndView();
		} else {
			return new ModelAndView("sys/500", "errMsg", errMsg);
		}
	}

	/**
	 * 获取异常的堆栈
	 * @param ex
	 * @return
	 */
	private String getTrace(Exception ex) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		ex.printStackTrace(pw);
		
		String str = sw.toString();
		
		StringBuffer sb = new StringBuffer();
		
		String[] arr = str.split("\r\n");
		for(String line : arr) {
			if(!line.startsWith("\t") || line.startsWith("\tat com.kc")) {
				sb.append(line+"\n");
			}
		}
		return sb.toString();
	}
	
	/**
	 * 判断请求是否为ajax
	 * @param req
	 * @return
	 */
	private boolean isAjax(HttpServletRequest req) {
		try {
			return !req.getHeader("accept").contains("text/html");
		} catch (Exception e) {
			return true;
		}
	}
	
	/**
	 * 通过resp写字符串
	 * @param resp
	 * @param str
	 */
	private static void write(HttpServletResponse resp, String str) {
		PrintWriter writer = null;
		try {
			resp.setCharacterEncoding("UTF-8");
			writer = resp.getWriter();
			writer.write(str);
			writer.flush();
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			if(writer != null) {
				writer.close();
			}
		}
	}
}
